#pragma once

#include "ogl/math/pch.h"
#include "ogl/math/Base.h"

namespace Ogl
{
	namespace Math
	{
		struct Transform 
		{

			glm::vec3 position = glm::vec3(0.0f);
			glm::vec3 rotation = glm::vec3(0.f);
			glm::vec3 scale = glm::vec3(1.0f);

			Transform();
			glm::vec3 GetRight() const;
			glm::vec3 GetForward() const;
			glm::vec3 GetUp() const;

			glm::mat4 GetViewMatrix() const;

			glm::mat4 GetViewMatrixNoTranslation() const;

			glm::mat4 GetWorld() const;

			glm::mat4 GetPosRotMatrix() const;

			Transform(const glm::vec3 &pos, const glm::quat &rot, const glm::vec3 &scale);

			void CreateFrom(const glm::mat4 &local);
			void RotateX(float d);
			void RotateY(float d);
			void RotateZ(float d);
			void Rotate(glm::vec3);
			void Decompose(const glm::mat4 &source);

			void SetPosition(const glm::vec3 &pos);
			void SetRotation(const glm::quat &q);
			void SetScale(const glm::vec3 &scale);

			void Scale(float d);

			void BackAt(glm::vec3 pos, glm::vec3 worldUp = glm::vec3(0.0f, 1.0f, 0.0f));
			void LookAt(glm::vec3 pos, glm::vec3 worldUp = glm::vec3(0.0f, 1.0f, 0.0f));

			glm::mat4 GetRotationMatrix() const;
			glm::quat GetRoatationQuat() const;

			void Move(float dist, glm::vec3 f);
			void Translate(float dist);
			void MoveRight(float dist);

			void Scale(glm::vec3 o, float d);
			glm::vec3 GetPosXZ() const;
			glm::vec3 GetPosYZ() const;
			glm::vec3 GetPosXY() const;

			float GetToXZSq();

			static glm::vec3 Xup();
			static glm::vec3 Zup();
			static glm::vec3 Yup();
			static Transform Slerp(const Transform &t1, const Transform &t2, float axis);
			static glm::vec3 GetEulerAnglesFromRotationMatrix(const glm::mat4 &rotationMatrix);
		};
	};
};